package fr.coding.kata.nantes.bench.fizzbuzz;

import fr.coding.kata.nantes.bench.AbstractRunner;
import fr.coding.kata.nantes.bench.Couple;
import fr.coding.kata.nantes.fizzbuzz.christophe.FizzerBuzzer;
import fr.coding.kata.nantes.fizzbuzz.commons.FizzBuzzInterface;
import fr.coding.kata.nantes.fizzbuzz.michel.PlayfullCountingSystem;
import fr.coding.kata.nantes.fizzbuzz.stephane.App;
import fr.coding.kata.nantes.fizzbuzz.sylvain.FizzBuzzGame;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Benchmark runner for the FizzBuzz kata implementations.
 *
 * @author Sylvain Leduby
 * @since 1.0
 */
public class FizzBuzzRunner extends AbstractRunner<FizzBuzzInterface, String, String> {

    /**
     * Implementations to run.
     */
    private static final List<FizzBuzzInterface> IMPLS;

    static {
        IMPLS = new ArrayList<FizzBuzzInterface>();
        // add your implementation here
        IMPLS.add(new FizzerBuzzer());
        IMPLS.add(new PlayfullCountingSystem());
        IMPLS.add(new App());
        IMPLS.add(new FizzBuzzGame());
    }

    public FizzBuzzRunner() {
        super(IMPLS, getData());
    }

    private static List<Couple<String, String>> getData() {
        final List<Couple<String, String>> dataset = new ArrayList<Couple<String, String>>();
        dataset.add(new Couple<String, String>(
                null,
                "1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n11\nFizz\n13\n14\nFizzBuzz\n16\n17\nFizz\n19\nBuzz\nFizz\n22\n23\nFizz\nBuzz\n26\nFizz\n28\n29\nFizzBuzz\n31\n32\nFizz\n34\nBuzz\nFizz\n37\n38\nFizz\nBuzz\n41\nFizz\n43\n44\nFizzBuzz\n46\n47\nFizz\n49\nBuzz\nFizz\n52\n53\nFizz\nBuzz\n56\nFizz\n58\n59\nFizzBuzz\n61\n62\nFizz\n64\nBuzz\nFizz\n67\n68\nFizz\nBuzz\n71\nFizz\n73\n74\nFizzBuzz\n76\n77\nFizz\n79\nBuzz\nFizz\n82\n83\nFizz\nBuzz\n86\nFizz\n88\n89\nFizzBuzz\n91\n92\nFizz\n94\nBuzz\nFizz\n97\n98\nFizz\nBuzz\n"));

        return dataset;
    }

    @Override
    public FizzBuzzInterface init(final FizzBuzzInterface target, final String input) {
        return target;
    }

    @Override
    protected boolean passed(final String expected, final String result) {
        // fix line separator
        final String filtered = StringUtils.remove(result, '\r');
        return expected.equals(filtered);
    }

}